/* mmuMipsLib.h - Memory Management Unit Library for MIPS */

/* Copyright (c) 1999-2000, 2003-2005 Wind River Systems, Inc. */

/*
modification history
--------------------
01y,23feb05,d_c  SPR 103891: Add bit to arch-dependent state word to
                 indicate user has access. Add bit to PTE to indicate
		 page is in kuseg. Corrected copyright.
01x,09dec04,pes  Remove setting the 8K page size bit in MMU_PTE_INIT_STATE.
                 This is an artifact of old code that encoded entryLo1 instead
		 of entryLo0.
01w,01nov04,slk  Add define for OSM error stack pointer
01v,22oct04,slk  SPR 92598: Add support for OSM handler and guard page size
                 storage in the exception page scratch area
01u,21sep04,sru  Added comment describing rationale for 8K MMU page size.
01t,15sep04,sru  Made MMU_PAGE_SIZE a simple constant, so that it can be
                 used as a parameter to the _WRS_DATA_ALIGN_BYTES directive.
01s,06aug04,sru  Add bitfields to pageMask portion of TLB.  Create TLB
                 structure for reading TLB hardware; update page masks.
01r,24mar04,slk  Modify definition of MMU_VA_TO_PFN_MASK for 16M rather than
                 4K page size.  Also rename MMU_VA_TO_PFN_MASK to
                 MMU_VA_TO_PFN_16M_MASK.
01q,02mar04,pes  Correct conditional expression for determining definition of
                 MMU_PTE_TLBLO0_OFFSET.
01p,17feb04,pes  Adjust offset to tlblo0 in PTE to deal with big-endian 32-bit
                 hosts.
01o,11dec03,jmt  Code Review changes
01n,08dec03,jmt  Incorporate Code Review changes
01m,02dec03,jmt  Continued Testing of MIPS AIM AD-MMU code
01l,19nov03,jmt  Continue development of MIPS AD-MMU code
01k,30oct03,jmt  rewrite as architecture-dependent portion of AIM MMU library
01j,16sep03,jmt  Modify TLB Handling for Base 6
01i,10sep03,jmt  Merge code from AE to Base 6
01h,12sep00,dra  Cleanup.
01g,30aug00,dra  Updated ASID fields.
01f,14jun00,dra  generalize the mmuMipsUnMap flush of virtual page address to
                 all Mips archs
01e,19apr00,dra  Expand MMU_MIPS_CONFIG to allow write protection of page
                 tables.  Add support for page unmap address flush.
01d,13apr00,dra  Added support for xTLB vector.
01c,24jan00,dra  Added pointer to mmuMipsConfig struct for
                 mmuMipsContextSet routine.
01b,15sep99,dra  Updated MMU_STATE macros.
01a,30jul99,dra  Created.
*/

/*
DESCRIPTION:

The MIPS family of devices range from the Toshiba TX3907 to the NEC VR4100
resulting in a wide range of implementations of memory management units.
This library contains the constant declarations, structures, and globals
that are generic to all of these devices.

The MIPS mmu library is a two-part library made from the generic library
module and a device-specific module; mmuMipsLib and mmuMipsxxxLib respectively.
This header file contains the data structure MMU_MIPS_CONFIG used to
interface the generic module to the device-specific one.  It also contains
declarations of all of the device-specific library initialization functions
as well as the generic one.

*/

#ifndef __INCmmuMipsLibh
#define __INCmmuMipsLibh

#ifdef __cplusplus
extern "C" {
#endif

#ifndef _ASMLANGUAGE
#include "aimMmuLib.h"
#endif

/* Defines */

/*
 * Table Entry Definitions
 * These are definitions for the indexes for the cache, protection
 * and mask tables defined for every device-dependent library
 */

/* Protection Table Indexes */

#define MMU_READWRITE   3
#define MMU_NO_WRITE	2
#define MMU_WRITE	32

/* Cache Table Indexes */

#define MMU_INVALID	0
#define MMU_CACHEOFF	1
#define MMU_CPYBACK	2
#define MMU_WRTHRU	3
#define MMU_COHRNT	4

/* Mask Table Indexes */

#define MMU_PMASK	1
#define MMU_VMASK	2
#define MMU_PVMASK	3
#define MMU_CMASK	4
#define MMU_PCMASK	5
#define MMU_VCMASK	6
#define MMU_PVCMASK	7

/* Temporary Storage offsets */

/* Exc page virtual base addrs */

#define EXCPAGE_VIRT_BASE_ADRS		0xFFFFE000

/* Exc scratch area when an Exc page is mapped in the TLB */

#define EXCPAGE_EXCSTUB_BASE		(-0x100)
#define EXCPAGE_EXCSTUB_AT		(EXCPAGE_EXCSTUB_BASE-0x08)
#define EXCPAGE_EXCSTUB_K0		(EXCPAGE_EXCSTUB_BASE-0x10)
#define EXCPAGE_EXCSTUB_K1		(EXCPAGE_EXCSTUB_BASE-0x18)
#define EXCPAGE_EXCSTUB_T0		(EXCPAGE_EXCSTUB_BASE-0x20)
#define EXCPAGE_EXCSTUB_T1		(EXCPAGE_EXCSTUB_BASE-0x28)
#define EXCPAGE_EXCSTUB_T2		(EXCPAGE_EXCSTUB_BASE-0x30)
#define EXCPAGE_EXCSTUB_T3		(EXCPAGE_EXCSTUB_BASE-0x38)
#define EXCPAGE_EXCSTUB_T4		(EXCPAGE_EXCSTUB_BASE-0x40)
#define EXCPAGE_EXCSTUB_T5		(EXCPAGE_EXCSTUB_BASE-0x48)
#define EXCPAGE_EXCSTUB_T6		(EXCPAGE_EXCSTUB_BASE-0x50)
#define EXCPAGE_EXCSTUB_T7		(EXCPAGE_EXCSTUB_BASE-0x58)
#define EXCPAGE_EXCSTUB_T8		(EXCPAGE_EXCSTUB_BASE-0x60)
#define EXCPAGE_EXCSTUB_T9		(EXCPAGE_EXCSTUB_BASE-0x68)
#define EXCPAGE_EXCSTUB_BVA		(EXCPAGE_EXCSTUB_BASE-0x70)
#define EXCPAGE_EXCSTUB_PC		(EXCPAGE_EXCSTUB_BASE-0x78)
#define EXCPAGE_EXCSTUB_TLBHI		(EXCPAGE_EXCSTUB_BASE-0x80)
#define EXCPAGE_EXCSTUB_CR		(EXCPAGE_EXCSTUB_BASE-0x88)
#define EXCPAGE_EXCSTUB_SR		(EXCPAGE_EXCSTUB_BASE-0x90)
#define EXCPAGE_EXCSTUB_SP		(EXCPAGE_EXCSTUB_BASE-0x98)

/* sigCtx scratch area when an Exc page is mapped in the TLB */

#define EXCPAGE_SIGCTX_BASE		(-0x200)
#define EXCPAGE_SIGCTX_T1		(EXCPAGE_SIGCTX_BASE-0x08)
#define EXCPAGE_SIGCTX_SR		(EXCPAGE_SIGCTX_BASE-0x10)
#define EXCPAGE_SIGCTX_PC		(EXCPAGE_SIGCTX_BASE-0x18)

/* MMU Miss handling scratch area when an Exc page is mapped in the TLB */

#define EXCPAGE_MMU_BASE                (-0x300)
#define EXCPAGE_MMU_HANDLER		(EXCPAGE_MMU_BASE-0x08)
#define EXCPAGE_MMU_CNTXT_TBL		(EXCPAGE_MMU_BASE-0x10)
#define EXCPAGE_MMU_VADDR_MASK	        (EXCPAGE_MMU_BASE-0x18)
#define EXCPAGE_MMU_VADDR_SHIFT 	(EXCPAGE_MMU_BASE-0x20)
#define EXCPAGE_MMU_MISS_COUNT  	(EXCPAGE_MMU_BASE-0x28)
#define EXCPAGE_MMU_MISS_COUNT_INS  	(EXCPAGE_MMU_BASE-0x30)

/* OSM handler support defines */

#define EXCPAGE_OSM_BASE                (-0x400)
#define EXCPAGE_OSM_HANDLER		(EXCPAGE_OSM_BASE-0x08)
#define EXCPAGE_OSM_GUARDPAGE_SIZE	(EXCPAGE_OSM_BASE-0x10)

/*
 * The MIPS MMU supports a hardware page size of 4K.  However, the MMU 
 * library treats each TLB register group as an entity for a single 
 * virtual->physical mapping.  So, the EntryLo0 and EntryLo1 registers
 * are always configured to map adjacent physical pages.  For this reason,
 * the de facto hardware page size is 2 * 4k, or 8K.
 */

#define MMU_PAGE_SIZE           0x2000  /* used in _WRS_ALIGN... directive */

/* TLB scratch area when an Exc page is mapped in the TLB */

#define TLB_EXCPAGE_AT		(-0x08)
#define TLB_EXCPAGE_K0		(-0x10)
#define TLB_EXCPAGE_K1		(-0x18)
#define TLB_EXCPAGE_T0		(-0x20)
#define TLB_EXCPAGE_T1		(-0x28)
#define TLB_EXCPAGE_T2		(-0x30)
#define TLB_EXCPAGE_T3		(-0x38)
#define TLB_EXCPAGE_T4		(-0x40)
#define TLB_EXCPAGE_T5		(-0x48)
#define TLB_EXCPAGE_T6		(-0x50)
#define TLB_EXCPAGE_T7		(-0x58)
#define TLB_EXCPAGE_T8		(-0x60)

/* MIPS common masks */ 

#define MIPS_R_ENTRY_MASK 0xFFC00000 /* Mask off top-10 bits in BVaddr */
#define MIPS_R_ENTRY_SHIFT	 22
#define MIPS_P_ENTRY_MASK 0x003FE000 /* Mask off middle-9 bits in BVaddr */

/* Context table information */

#define MMU_GLOBAL_CONTEXT	0
#define MMU_FIRST_LOCAL_CONTEXT 1
#define MMU_LAST_LOCAL_CONTEXT	255

/* Page size support information */

/* MMU_PAGE_SIZES_STANDARD are page sizes supported by standard MIPS h/w */

#define MMU_PAGE_SIZES_STANDARD (MMU_PAGE_MASK_8K   | \
				 MMU_PAGE_MASK_32K  | \
				 MMU_PAGE_MASK_128K | \
				 MMU_PAGE_MASK_512K | \
				 MMU_PAGE_MASK_2M   | \
				 MMU_PAGE_MASK_8M   | \
				 MMU_PAGE_MASK_32M)

/* MMU_PAGE_SIZES_ALLOWED are page sizes supported by the MIPS AD-MMU */

#define MMU_PAGE_SIZES_ALLOWED	(MMU_PAGE_MASK_8K   | \
				 MMU_PAGE_MASK_32K  | \
				 MMU_PAGE_MASK_128K | \
				 MMU_PAGE_MASK_512K | \
				 MMU_PAGE_MASK_2M)

#define MMU_MAX_PAGE_SIZES	5


/* R4K Hardware TLB definitions */

#define TLB_4K_PAGE_SIZE        0x00001000
#define TLB_16K_PAGE_SIZE       0x00004000
#define TLB_64K_PAGE_SIZE       0x00010000
#define TLB_256K_PAGE_SIZE      0x00040000
#define TLB_1M_PAGE_SIZE        0x00100000
#define TLB_4M_PAGE_SIZE        0x00400000
#define TLB_16M_PAGE_SIZE       0x01000000

#define TLB_4K_PAGE_SIZE_MASK   0x00000000 
#define TLB_16K_PAGE_SIZE_MASK  0x00006000 
#define TLB_64K_PAGE_SIZE_MASK  0x0001E000 
#define TLB_256K_PAGE_SIZE_MASK 0x0007E000 
#define TLB_1M_PAGE_SIZE_MASK   0x001FE000 
#define TLB_4M_PAGE_SIZE_MASK   0x007FE000 
#define TLB_16M_PAGE_SIZE_MASK  0x01FFE000 

#define TLB_PAGE_MASK_SHIFT             13  /* lower 13 bits must be 0 */

/* R4K TLB definitions
 * - does not match hardware definitions
 * The software will use page sizes twice the Hardware TLB page size
 * The page size mask does not change.
 */

#define TLB_8K_PAGE_SIZE        (2*TLB_4K_PAGE_SIZE)
#define TLB_32K_PAGE_SIZE       (2*TLB_16K_PAGE_SIZE)
#define TLB_128K_PAGE_SIZE      (2*TLB_64K_PAGE_SIZE)
#define TLB_512K_PAGE_SIZE      (2*TLB_256K_PAGE_SIZE)
#define TLB_2M_PAGE_SIZE        (2*TLB_1M_PAGE_SIZE)
#define TLB_8M_PAGE_SIZE        (2*TLB_4M_PAGE_SIZE)
#define TLB_32M_PAGE_SIZE       (2*TLB_16M_PAGE_SIZE)

#define TLB_8K_PAGE_SIZE_MASK   TLB_4K_PAGE_SIZE_MASK
#define TLB_32K_PAGE_SIZE_MASK  TLB_16K_PAGE_SIZE_MASK
#define TLB_128K_PAGE_SIZE_MASK TLB_64K_PAGE_SIZE_MASK
#define TLB_512K_PAGE_SIZE_MASK TLB_256K_PAGE_SIZE_MASK
#define TLB_2M_PAGE_SIZE_MASK   TLB_1M_PAGE_SIZE_MASK
#define TLB_8M_PAGE_SIZE_MASK   TLB_4M_PAGE_SIZE_MASK
#define TLB_32M_PAGE_SIZE_MASK  TLB_16M_PAGE_SIZE_MASK

#define TLB_8K_PFN_MASK         0x3FFFFF80
#define TLB_32K_PFN_MASK        0x3FFFFE00
#define TLB_128K_PFN_MASK       0x3FFFF800
#define TLB_512K_PFN_MASK       0x3FFFE000
#define TLB_2M_PFN_MASK         0x3FFF8000
#define TLB_8M_PFN_MASK         0x3FFE0000
#define TLB_32M_PFN_MASK        0x3FF80000

#define TLB_2M_VADDR_MASK       0x00200000
#define TLB_512K_VADDR_MASK     0x00380000
#define TLB_128K_VADDR_MASK     0x003E0000
#define TLB_32K_VADDR_MASK      0x003F8000
#define TLB_8K_VADDR_MASK       0x003FE000

#define TLB_2M_VADDR_SHIFT      (21 - MMU_PTE_SIZE_SHIFT)
#define TLB_512K_VADDR_SHIFT    (19 - MMU_PTE_SIZE_SHIFT)
#define TLB_128K_VADDR_SHIFT    (17 - MMU_PTE_SIZE_SHIFT)
#define TLB_32K_VADDR_SHIFT     (15 - MMU_PTE_SIZE_SHIFT)
#define TLB_8K_VADDR_SHIFT      (13 - MMU_PTE_SIZE_SHIFT)

/* Page Table Size defines
 * These define the page table size for each of the page sizes.
 * Use the smallest page size supported
 */
#define TLB_2M_TABLE_SIZE       2
#define TLB_512K_TABLE_SIZE     (4 * TLB_2M_TABLE_SIZE)
#define TLB_128K_TABLE_SIZE     (4 * TLB_512K_TABLE_SIZE)
#define TLB_32K_TABLE_SIZE      (4 * TLB_128K_TABLE_SIZE)
#define TLB_8K_TABLE_SIZE       (4 * TLB_32K_TABLE_SIZE)

/* State Defines */

#define MMU_BASE_STATE       0x00000000

/* EntryLo Defines */

#define MMU_R4K_4K_PFN_MASK         0x3FFFFFC0
#define MMU_R4K_4K_PFN2_MASK        0x3FFFFF80  /* mask for 2 pages */
#define MMU_R4K_VPN2_SHIFT          13		/* right shift justify VPN of
						 * address
						 */
#define MMU_R4K_PFN_SHIFT           6		/* left shift for PFN loc */
#define MMU_R4K_STATE_VALID	    0x00000002  /* V flag set      */
#define MMU_R4K_STATE_VALID_NOT	    0x00000000  /* V flag reset    */
#define MMU_R4K_STATE_WRITABLE	    0x00000004  /* D flag set      */
#define MMU_R4K_STATE_WRITABLE_NOT  0x00000000  /* D flag reset    */  
#define MMU_R4K_STATE_INVALID_STATE 0xC0000000  /* Invalid State   */
#define MMU_R4K_STATE_GLOBAL	    0x00000001  /* G flag set      */
#define MMU_R4K_UNCACHED            0x00000010
#define MMU_R4K_CACHED              0x00000018

#define MMU_R4K_GLOBAL_START     0           /* Start point of global bit */
#define MMU_R4K_VALID_START      1           /* Start point of valid bit  */
#define MMU_R4K_DIRTY_START      2           /* Start point of dirty bit  */
#define MMU_R4K_CACHE_START      3           /* Start point of cache field*/

/* Masks */

#define MMU_R4K_STATE_MASK_VALID	0x00000002
#define MMU_R4K_STATE_MASK_WRITABLE	0x00000004
#define MMU_R4K_STATE_MASK_CACHEABLE    0x00000038
#define MMU_R4K_TLBLO_MODE_MASK         0x0000003e

/* State and mask definitions for attributes maintained within PageMask */

#define MMU_STATE_MASK_LOCKED		0x00000100
#define MMU_STATE_LOCKED		0x00000100
#define MMU_STATE_MASK_ISR_CALLABLE	0x00000200
#define MMU_STATE_ISR_CALLABLE		0x00000200
#define MMU_STATE_MASK_USER_ACCESS      0x00000400
#define MMU_STATE_USER_ACCESS           0x00000400
#define MMU_STATE_USER_ACCESS_NOT       0x00000000

/* EntryHi Defines */

#define MMU_R4K_VPN2_MASK           0xffffe000      /* page no mask */
#define MMU_R4K_ASID_MASK           0x000000ff
#define MMU_VA_TO_PFN_16M_MASK      0x1e000000      /* 16M page mask */
#define MMU_NUM_ASID                256
#define MMU_R4K_PAGE_SHIFT          12     /* convert VM pagenum to VA */

/*
 * Table Entry Definitions
 * These are definitions for the indexes for the cache, protection
 * and mask tables defined for every device-dependent library
 */

/* Protection Table Indexes */

#define MMU_READWRITE   3
#define MMU_NO_WRITE	2
#define MMU_WRITE	32

/* Cache Table Indexes */

#define MMU_INVALID	0
#define MMU_CACHEOFF	1
#define MMU_CPYBACK	2
#define MMU_WRTHRU	3
#define MMU_COHRNT	4

/* Mask Table Indexes */

#define MMU_PMASK	1
#define MMU_VMASK	2
#define MMU_PVMASK	3
#define MMU_CMASK	4
#define MMU_PCMASK	5
#define MMU_VCMASK	6
#define MMU_PVCMASK	7

/* TLB Miss Setup Structure offsets */

#define MMU_SETUP_VADDR_MASK_OFFSET  0x0
#define MMU_SETUP_PAGE_MASK_OFFSET   0x4
#define MMU_SETUP_ENTRYLO0_OR_OFFSET 0x8
#define MMU_SETUP_TABLE_SIZE_OFFSET  0xc
#define MMU_SETUP_VADDR_SHIFT_OFFSET 0x10

/* PTE Defines */

#define MMU_BYTES_PER_ENTRY	   16	/* Num bytes per page table entry */
#define MMU_PTE_SIZE_SHIFT         4
#define MMU_PTE_PAGE_MASK_OFFSET   0x00
#define MMU_PTE_ENTRYLO1_OR_OFFSET 0x04
#if defined (_WRS_PHYS_ADDR_IS_64_BITS) && (_BYTE_ORDER == _BIG_ENDIAN) && (_WRS_INT_REGISTER_SIZE == 4)
#define MMU_PTE_TLBLO0_OFFSET      0x0c
#else /* _WRS_PHYS_ADDR_IS_64_BITS) && (_BYTE_ORDER == _BIG_ENDIAN) */
#define MMU_PTE_TLBLO0_OFFSET      0x08
#endif /* _WRS_PHYS_ADDR_IS_64_BITS) && (_BYTE_ORDER == _BIG_ENDIAN) */

#define MMU_PTE_TBLPTR_MASK      0xFFFFFFFE
#define MMU_PTE_TERM_MASK        0x00000001
#define MMU_PTE_NOT_TERM         0x00000000
#define MMU_PTE_TERM             0x00000001

#define MMU_TEMP_TLB_STATE (MMU_R4K_STATE_VALID | MMU_R4K_CACHED | \
			    MMU_R4K_STATE_WRITABLE | MMU_R4K_STATE_GLOBAL)
#define MMU_PTE_INIT_STATE (MMU_R4K_UNCACHED | MMU_R4K_STATE_WRITABLE)


#ifndef _ASMLANGUAGE

/* The Page-Table Entry (PTE) Structure */

typedef struct
    {
#if (_BYTE_ORDER == _BIG_ENDIAN)
    UINT32      pageMask:19;
    UINT32	reserved:10;
    UINT32      isKuseg:1;
    UINT32	isr:1;
    UINT32	locked:1;	/* LSB */
#else   /* _BYTE_ORDER == _BIG_ENDIAN */
    UINT32	locked:1;	/* LSB */
    UINT32	isr:1;
    UINT32      isKuseg:1;
    UINT32	reserved:10;
    UINT32      pageMask:19;
#endif  /* _BYTE_ORDER == _BIG_ENDIAN */
    UINT32      entryLo1OrValue;
    PHYS_ADDR   entryLo0;
    } PTE;

/* Define the TLB Structure.  ASM code assumes this is 24 bytes. */

typedef struct
    {
#if (_WRS_INT_REGISTER_SIZE == 8)
    UINT64	entryHi;
#else  /* (_WRS_INT_REGISTER_SIZE != 8) */
    UINT32	entryHi;
    UINT32	pad1;
#endif /* (_WRS_INT_REGISTER_SIZE != 8) */
    UINT32      entryLo0;
    UINT32	entryLo1;
    UINT32	pageMask;
    UINT32	pad2;
    } MIPS_TLB_ENTRY;


typedef void      (*MMUMIPSTLBCLRFUNC)(UINT, UINT, VIRT_ADDR);
typedef void      (*MMUMIPSTLBCLRALLFUNC)(UINT);
typedef void      (*MMUMIPSTLBWIREDENTRYSETFUNC)(UINT32, PTE *);
typedef void      (*MMUMIPSTLBENABLEFUNC)(UINT,UINT,UINT,FUNCPTR);
typedef void      (*MMUMIPSTLBVECFUNC)(void);

/* 
 * TLB Setup structure for Miss handler
 *
 * This structure holds the information needed by the TLB Miss Handler
 * to setup the TLB entry.
 */

typedef struct
    {
    UINT32   vAddrMask;
    UINT32   pageMask;
    UINT32   entryLo0OrValue;
    UINT32   tableSize;
    UINT32   vAddrShift;
    } MIPS_TLB_SETUP_STRUCT;

/*
 * This is the structure used to configure the mmu library
 * for the varying MIPS architectures.	
 */

typedef struct mmuMipsConfigStruct
    {
    int  nTlbEntries;   /* Number of Entries in TLB */
    
    UINT minPageSize;	/* minimum size of pages, 8k or greater	*/
    
    UINT tlbVector;	/* Value of TLB vector for device */
    UINT xtlbVector;	/* Value of XTLB vector for device */
    
    /* Pointers to subroutines for MIPS device-specific needs */

    MMUMIPSTLBCLRFUNC      ptrMmuInvalidateRtn;    /* Invalidate Entry */
    MMUMIPSTLBCLRALLFUNC   ptrMmuInvalidateAllRtn; /* Invalidate All   */
    } MMU_MIPS_CONFIG;

IMPORT MMU_MIPS_CONFIG mmuMipsConfig;

/* Prototypes for MIPS supported MMU Initialization routines */

IMPORT STATUS mmuMipsLibInit ();


#endif  /* ifndef _ASMLANGUAGE */

#ifdef __cplusplus
}
#endif

#endif  /* __INCmmuMipsLibh */
